import { ElMessage } from 'element-plus'
import { convertCurrency } from '@/utils/helper'
import { getSingleSalesInfo } from '@/api/single'
import { getOrderQrcode } from '@/api/print'
// 新增DOM节点打印方法
export const printSingleDOM = async (selectList: any, str = '销售送货单') => {
  if (selectList.length === 0) {
    ElMessage.warning('请选择要打印的订单')
    return
  }
  if (selectList.length > 1) {
    ElMessage.warning('单次只能打印一张订单')
    return
  }
  if (selectList[0].order_status === 7)
    return ElMessage.warning('该订单已取消,无法打印')
  // 直接打开路由，通过路由参数传递id和title
  window.open(
    `/#/single/printSingle?id=${selectList[0].id}&title=${encodeURIComponent(str)}`,
    '_blank'
  )
}

// 原有的Canvas打印方法
export const printSingle = async (selectList: any, str = '销售送货单') => {
  if (selectList.length === 0) {
    ElMessage.warning('请选择要打印的订单')
    return
  }
  if (selectList.length > 1) {
    ElMessage.warning('单次只能打印一张订单')
    return
  }
  if (selectList[0].order_status === 7)
    return ElMessage.warning('该订单已取消,无法打印')
  const { data }: any = await getSingleSalesInfo({ id: selectList[0].id })
  const orderInfo: any = data
  // 预先计算内容高度
  let spec = orderInfo.order_detail[0].goods_spec_name.split('??')
  // 准备数据
  const orderData: any = {
    title: orderInfo.base_info.supplier_name,
    subTitle: str,
    orderNo: orderInfo.base_info.order_sn,
    date: orderInfo.base_info.create_time,
    customer: orderInfo.base_info.shop_name,
    seller: orderInfo.base_info.sales_person_name,
    items: orderInfo.order_detail.map((goods, index) => {
      let specLabel = spec
      let specValue = goods.goods_value_name.split('??')
      let obj = {
        no: index + 1,
        name: goods.product_name || goods.goods_name,
        quantity: Number(goods.quantity || 0),
        price: Number(goods.price || 0),
        amount: Number(goods.price || 0) * Number(goods.quantity || 0),
        remark: goods.remark || '',
        brand_name: goods.brand_name || '',
      }
      specLabel.forEach((item, index) => {
        obj[item] = specValue[index] || '无'
      })
      return obj
    }),
    total: {
      quantity: orderInfo.order_detail.reduce(
        (total, goods) => total + goods.quantity,
        0
      ),
      amount: Number(orderInfo.base_info.pay_amount),
    },
    maker: orderInfo.base_info.sales_person_name,
    customer_sign: '客户签字:___________',
  }

  // 定义基本参数
  const headerHeight = 220 // 标题和基本信息的高度
  const baseRowHeight = 30 // 每行基本高度
  const footerHeight = 100 // 合计行、签名等底部内容高度

  // 预估每行实际高度 - 可能因为内容换行而增加
  const estimatedRowsHeight = orderData.items.reduce((total, item) => {
    // 检查内容是否需要换行，简单估算
    const nameLines = Math.ceil(`(${item.brand_name}) ${item.name}`.length / 12) // 假设每行12个字符
    const specLines = spec.reduce((max, s) => {
      const specValue = item[s] || ''
      return Math.max(max, Math.ceil(specValue.length / 6))
    }, 1)
    const remarkLines = item.remark ? Math.ceil(item.remark.length / 10) : 1
    const maxLines = Math.max(nameLines, specLines, remarkLines)

    // 计算这行的估计高度
    const estimatedRowHeight = Math.max(baseRowHeight, maxLines * 16 + 10)
    return total + estimatedRowHeight
  }, 0)
  // 计算总高度
  const estimatedTotalHeight = headerHeight + estimatedRowsHeight + footerHeight
  // 创建一个离屏Canvas，高度根据内容动态计算
  const canvas = document.createElement('canvas')
  const ctx = canvas.getContext('2d')

  // 设置画布大小
  canvas.width = 800
  canvas.height = Math.max(estimatedTotalHeight, 600) // 最小高度600px

  // 绘制白色背景
  ctx.fillStyle = '#FFFFFF'
  ctx.fillRect(0, 0, canvas.width, canvas.height)

  // 设置基本字体样式
  ctx.textBaseline = 'middle'
  ctx.textAlign = 'left'

  // 计算金额大写
  orderData.total.amountInWords = convertCurrency(orderData.total.amount)

  // 绘制抬头
  ctx.font = 'bold 24px 黑体 serif'
  ctx.fillStyle = '#000000'
  ctx.textAlign = 'center'
  ctx.fillText(orderData.title, canvas.width / 2, 80)

  ctx.font = 'bold 24px 黑体 serif'
  ctx.fillText(orderData.subTitle, canvas.width / 2, 110)

  // 绘制基本信息 - 调整为四个数据一排
  ctx.textAlign = 'left'
  ctx.font = '15px 黑体 serif'

  // 第一行信息
  const infoY1 = 150
  ctx.fillText(`客户：${orderData.customer}`, 38, infoY1)
  ctx.fillText(`销售人：${orderData.seller}`, 180, infoY1)
  ctx.fillText(`单据日期：${orderData.date.substring(0, 10)}`, 320, infoY1)
  ctx.fillText(`单据编号：${orderData.orderNo}`, 500, infoY1)
  // 绘制二维码
  await generateQRCode(selectList[0].id, ctx, 80, 50, 80, 80)
  // 绘制表格表头
  const startY = 180
  const rowHeight = baseRowHeight // 与图片一致的行高
  const cellPadding = 5 // 减小单元格内边距

  // 调整列宽，确保最后一列备注有足够宽度
  const specColumns = spec.length // 获取规格列数量
  const colWidths = [
    40, // 序号
    140, // 商品名称
    ...Array(specColumns).fill(120), // 规格列宽度
    60, // 数量
    70, // 单价
    70, // 金额
    100, // 备注
  ]

  // 计算表格总宽度
  const tableWidth = colWidths.reduce((total, width) => total + width, 0)
  const tableStartX = (canvas.width - tableWidth) / 2

  // 绘制表头 - 移除背景色
  ctx.strokeStyle = '#000000'
  ctx.lineWidth = 1
  ctx.strokeRect(tableStartX, startY, tableWidth, rowHeight)

  // 绘制表头分隔线
  let currentX = tableStartX
  for (const width of colWidths) {
    currentX += width
    ctx.beginPath()
    ctx.moveTo(currentX, startY)
    ctx.lineTo(currentX, startY + rowHeight)
    ctx.stroke()
  }

  // 表头文字
  const headers = [
    '序号',
    '商品名称',
    ...spec, // 展开规格列表
    '数量',
    '单价',
    '金额',
    '备注',
  ]
  ctx.fillStyle = '#000000'
  ctx.font = 'bold 14px 黑体 Arial'

  currentX = tableStartX
  for (let i = 0; i < headers.length; i++) {
    const centerX = currentX + colWidths[i] / 2
    ctx.textAlign = 'center'
    ctx.fillText(headers[i], centerX, startY + rowHeight / 2)
    currentX += colWidths[i]
  }

  // 绘制表格内容
  let currentY = startY + rowHeight
  let actualHeight = 0 // 记录实际内容高度

  orderData.items.forEach((item, index) => {
    // 计算当前行需要的高度（根据内容多少动态调整）
    const nameLineHeight = 16 // 减小行高使其更接近图片
    const specLineHeight = 16
    const remarkLineHeight = 16

    // 保存当前的textAlign设置
    const originalTextAlign = ctx.textAlign
    ctx.textAlign = 'center'
    ctx.font = '12px Arial'

    // 预计算文本行数
    const nameLinesCount = Math.max(
      1,
      Math.ceil(
        ctx.measureText(`(${item.brand_name}) ${item.name}`).width /
          (colWidths[1] - 10)
      )
    )

    // 计算规格文本的行数
    let maxSpecLinesCount = 1
    for (let i = 0; i < spec.length; i++) {
      const specValue = item[spec[i]] || ''
      const specLinesCount = Math.max(
        1,
        Math.ceil(ctx.measureText(specValue).width / (colWidths[i + 2] - 10))
      )
      maxSpecLinesCount = Math.max(maxSpecLinesCount, specLinesCount)
    }

    const remarkLinesCount = item.remark
      ? Math.max(
          1,
          Math.ceil(
            ctx.measureText(item.remark).width /
              (colWidths[spec.length + 5] - 10)
          )
        )
      : 1

    // 计算此行所需的最大行数
    const maxLinesCount = Math.max(
      nameLinesCount,
      maxSpecLinesCount,
      remarkLinesCount
    )

    // 计算此行的高度
    const currentRowHeight = Math.max(
      rowHeight,
      maxLinesCount * nameLineHeight + cellPadding * 2 // 添加上下内边距
    )

    // 绘制行背景和边框
    ctx.strokeRect(tableStartX, currentY, tableWidth, currentRowHeight)

    // 绘制单元格分隔线
    let cellX = tableStartX
    for (const width of colWidths) {
      cellX += width
      ctx.beginPath()
      ctx.moveTo(cellX, currentY)
      ctx.lineTo(cellX, currentY + currentRowHeight)
      ctx.stroke()
    }

    // 绘制单元格内容
    cellX = tableStartX

    // 序号
    ctx.fillText(
      item.no.toString(),
      cellX + colWidths[0] / 2,
      currentY + currentRowHeight / 2
    )
    cellX += colWidths[0]

    // 商品名称（支持换行）
    ctx.textAlign = 'center'
    drawWrappedText(
      ctx,
      `(${item.brand_name}) ${item.name}`,
      cellX + colWidths[1] / 2,
      currentY +
        cellPadding +
        (currentRowHeight - cellPadding * 2) / 2 -
        ((nameLinesCount - 1) * nameLineHeight) / 2,
      colWidths[1] - 10,
      nameLineHeight
    )
    cellX += colWidths[1]

    // 规格列（循环显示每个规格值）
    for (let i = 0; i < spec.length; i++) {
      const specValue = item[spec[i]] || '' // 移除toLowerCase()
      drawWrappedText(
        ctx,
        specValue,
        cellX + colWidths[i + 2] / 2,
        currentY + cellPadding + (currentRowHeight - cellPadding * 2) / 2,
        colWidths[i + 2] - 10,
        specLineHeight
      )
      cellX += colWidths[i + 2]
    }

    // 数量
    ctx.textAlign = 'center'
    ctx.fillText(
      item.quantity.toString(),
      cellX + colWidths[spec.length + 2] / 2,
      currentY + currentRowHeight / 2
    )
    cellX += colWidths[spec.length + 2]

    // 单价
    ctx.fillText(
      item.price.toFixed(2),
      cellX + colWidths[spec.length + 3] / 2,
      currentY + currentRowHeight / 2
    )
    cellX += colWidths[spec.length + 3]

    // 金额
    ctx.fillText(
      item.amount.toFixed(2),
      cellX + colWidths[spec.length + 4] / 2,
      currentY + currentRowHeight / 2
    )
    cellX += colWidths[spec.length + 4]

    // 备注
    ctx.textAlign = 'center'
    if (item.remark) {
      drawWrappedText(
        ctx,
        item.remark,
        cellX + colWidths[spec.length + 5] / 2,
        currentY +
          cellPadding +
          (currentRowHeight - cellPadding * 2) / 2 -
          ((remarkLinesCount - 1) * remarkLineHeight) / 2,
        colWidths[spec.length + 5] - 10,
        remarkLineHeight
      )
    }

    // 恢复原始的textAlign设置
    ctx.textAlign = originalTextAlign

    currentY += currentRowHeight
  })

  // 绘制合计行
  ctx.strokeRect(tableStartX, currentY, tableWidth, rowHeight)

  // 计算合并单元格的宽度（从序号到数量前面的所有列）
  const mergedCellWidth = colWidths
    .slice(0, spec.length + 2)
    .reduce((a, b) => a + b, 0)

  // 绘制合计行分隔线 - 只绘制合并单元格后面的分隔线
  // 首先绘制合并单元格与数量列的分隔线
  ctx.beginPath()
  ctx.moveTo(tableStartX + mergedCellWidth, currentY)
  ctx.lineTo(tableStartX + mergedCellWidth, currentY + rowHeight)
  ctx.stroke()

  // 然后绘制数量列及之后的分隔线
  let totalCellX = tableStartX + mergedCellWidth
  for (let i = 0; i < 4; i++) {
    // 4列：数量、单价、金额、备注
    totalCellX += colWidths[spec.length + 2 + i]
    ctx.beginPath()
    ctx.moveTo(totalCellX, currentY)
    ctx.lineTo(totalCellX, currentY + rowHeight)
    ctx.stroke()
  }

  // 合计行文字
  ctx.fillStyle = '#000000'
  ctx.font = 'bold 14px Arial'

  // 合计标签 - 居左显示
  ctx.textAlign = 'left'
  ctx.fillText('合计', tableStartX + 10, currentY + rowHeight / 2)

  // 合计数量
  const quantityColX = tableStartX + mergedCellWidth
  ctx.textAlign = 'center'
  ctx.fillText(
    orderData.total.quantity.toString(),
    quantityColX + colWidths[spec.length + 2] / 2,
    currentY + rowHeight / 2
  )

  // 合计金额
  const amountColX =
    quantityColX + colWidths[spec.length + 2] + colWidths[spec.length + 3]
  ctx.fillText(
    orderData.total.amount.toFixed(2),
    amountColX + colWidths[spec.length + 4] / 2,
    currentY + rowHeight / 2
  )

  // 绘制合计大写 - 合并所有单元格
  currentY += rowHeight
  ctx.strokeRect(tableStartX, currentY, tableWidth, rowHeight)
  ctx.textAlign = 'left'
  ctx.font = '14px Arial'
  ctx.fillText(
    `合计金额大写: ${orderData.total.amountInWords}`,
    tableStartX + 10,
    currentY + rowHeight / 2
  )

  // 绘制底部信息 - 放在同一行
  currentY += rowHeight + 25
  ctx.font = '14px Arial'
  ctx.fillText(`制单人：${orderData.maker}`, tableStartX, currentY)
  ctx.fillText(
    orderData.customer_sign,
    tableStartX + tableWidth - 150,
    currentY
  )

  // 添加打印时间
  // currentY += 20
  // ctx.textAlign = 'center'
  // ctx.fillText(
  //   `电话: ${orderInfo.distribution_info.consignee_mobile}    打印时间: ${new Date().toLocaleString()}`,
  //   canvas.width / 2,
  //   currentY
  // )

  // 记录实际内容高度
  actualHeight = currentY + 30

  // 如果实际高度小于画布高度，裁剪画布
  if (actualHeight < canvas.height) {
    const tempCanvas = document.createElement('canvas')
    tempCanvas.width = canvas.width
    tempCanvas.height = actualHeight
    const tempCtx = tempCanvas.getContext('2d')
    tempCtx.drawImage(canvas, 0, 0)
    canvas.height = actualHeight
    ctx.drawImage(tempCanvas, 0, 0)
  }

  // 转换Canvas为图片
  const printWindow = window.open('', '_blank')

  if (!printWindow) {
    ElMessage.error('打印窗口被阻止，请允许弹出窗口后重试')
    return
  }

  // 使用分页布局模式，防止大量数据时首页空白
  printWindow.document.write(`
      <html>
        <head>
          <title>打印销售单</title>
          <style>
            body {
              margin: 0;
              padding: 0;
              text-align: center;
              background-color: #ffffff;
            }
            img {
              display: block;
              max-width: 100%;
              page-break-inside: avoid;
              page-break-after: auto;
              margin: 0 auto;
              height: auto;
            }
            .print-container {
              margin: 0 auto;
              padding: 0;
              max-width: 800px;
              background-color: #ffffff;
            }
            .print-buttons {
              margin: 20px 0;
              page-break-inside: avoid;
              page-break-before: avoid;
            }
            .print-buttons button {
              padding: 6px 16px;
              margin: 0 10px;
              border: none;
              border-radius: 4px;
              cursor: pointer;
              font-size: 14px;
            }
            .print-buttons button.print {
              background-color: #409EFF;
              color: white;
            }
            .print-buttons button.close {
              background-color: #909399;
              color: white;
            }
            @media print {
              html, body {
                margin: 0;
                padding: 0;
                height: auto;
              }
              .print-buttons {
                display: none;
              }
              @page {
                size: auto;
                margin: 0;
              }
            }
          </style>
          <script>
            function handlePrint() {
              window.print();
            }
            
            function handleClose() {
              window.close();
            }
            
            // 图片加载完成后自动调用打印
            window.onload = function() {
              // 确保图片已完全加载
              var img = document.querySelector('img');
              if (img.complete) {
                printAfterDelay();
              } else {
                img.onload = printAfterDelay;
              }
            };
            
            function printAfterDelay() {
              // 延迟稍长一点以确保渲染完成
              setTimeout(function() {
                window.print();
                // 打印对话框关闭后执行
                window.addEventListener('afterprint', function() {
                  // setTimeout(function() { window.close(); }, 1000);
                });
              }, 1000);
            }
          </script>
        </head>
        <body>
          <div class="print-container">
            <img src="${canvas.toDataURL('image/svg', 1.0)}" />
            <div class="print-buttons">
              <button class="print" onclick="handlePrint()">打印</button>
              <button class="close" onclick="handleClose()">关闭</button>
            </div>
          </div>
        </body>
      </html>
    `)

  printWindow.document.close()

  // 确保打印窗口获得焦点
  printWindow.focus()
}

// 生成二维码的函数
const generateQRCode = (id, ctx, x, y, width, height) => {
  return new Promise( async (resolve, reject) => {

    const res = await getOrderQrcode({
      page: 'pagesShop/order/orderInfo',
      scene: `id=${id}`,
      env_version: process.env.VUE_APP_VERSION,
    }) 
    //插入一张二维码的图片
    const img = new Image()
    img.crossOrigin = 'Anonymous' // 解决可能的跨域问题
    img.src = res.data

    img.onload = () => {
      ctx.drawImage(img, x, y, width, height)
      resolve(true) // 图片加载完成后解析Promise
    }

    img.onerror = (error) => {
      console.error('二维码图片加载失败', error)
      // 加载失败时绘制一个占位框
      ctx.fillStyle = '#FFFFFF'
      ctx.fillRect(x, y, width, height)
      ctx.strokeStyle = '#000000'
      ctx.lineWidth = 1
      ctx.strokeRect(x, y, width, height)
      ctx.fillStyle = '#000000'
      ctx.font = '12px Arial'
      ctx.textAlign = 'center'
      ctx.fillText('二维码加载失败', x + width / 2, y + height / 2)
      reject() // 即使失败也解析Promise，避免阻塞
    }

    // 设置超时处理
    setTimeout(() => {
      if (!img.complete) {
        img.src = '' // 取消加载
        // 绘制一个占位框
        ctx.fillStyle = '#FFFFFF'
        ctx.fillRect(x, y, width, height)
        ctx.strokeStyle = '#000000'
        ctx.lineWidth = 1
        ctx.strokeRect(x, y, width, height)
        ctx.fillStyle = '#000000'
        ctx.font = '12px Arial'
        ctx.textAlign = 'center'
        ctx.fillText('二维码加载超时', x + width / 2, y + height / 2)
        reject() // 超时也解析Promise
      }
    }, 3000) // 3秒超时
  })
}

// 文本自动换行绘制函数
const drawWrappedText = (ctx, text, x, y, maxWidth, lineHeight) => {
  if (!text) return

  const words = text.split('')
  let line = ''
  let testLine = ''
  let lineCount = 0
  const metrics = ctx.measureText(text)
  const testWidth = metrics.width

  // 如果文本宽度不超过最大宽度，直接绘制
  if (testWidth <= maxWidth) {
    ctx.fillText(text, x, y)
    return 1 // 返回行数
  }

  // 否则进行文本换行
  for (let n = 0; n < words.length; n++) {
    testLine = line + words[n]
    const metrics = ctx.measureText(testLine)
    const testWidth = metrics.width

    if (testWidth > maxWidth && n > 0) {
      ctx.fillText(line, x, y + lineCount * lineHeight)
      line = words[n]
      lineCount++
    } else {
      line = testLine
    }
  }

  // 绘制最后一行
  ctx.fillText(line, x, y + lineCount * lineHeight)
  return lineCount + 1 // 返回行数
}
